package org.bee.controller;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.bee.enums.FileType;
import org.bee.enums.IsDelete;
import org.bee.enums.ResultCode;
import org.bee.exception.ExceptionUtils;
import org.bee.file.FileUtils;
import org.bee.id.UUIDUtils;
import org.bee.input.SysFileInsertVo;
import org.bee.input.SysFileSearchVo;
import org.bee.input.SysFileUpdateVo;
import org.bee.model.SysFile;
import org.bee.PageUtil;
import org.bee.model.result.Result;
import org.bee.ResultTool;
import org.bee.output.SysFileOut;
import org.bee.secuirty.annotation.ApiAuth;
import org.bee.secuirty.context.CurrentUser;
import org.bee.service.SysFileService;
import org.bee.transaction.TransUtils;
import org.bee.transaction.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.bee.string.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 文件表控制器
 */
@RestController
@RequestMapping("/sysFile")
public class SysFileController {
    Logger logger = LoggerFactory.getLogger(SysFileController.class);

    @Resource
    private SysFileService sysFileService;

    @Value("${fileSavePath}")
    private String fileSavePath;

    /**
     * 新增文件表
     * @param sysFileInsertVo 新增参数
     * @return 新增结果
     */
    @PostMapping("insert")
    @ApiAuth(value="sysFile.insert",description= "新增文件表")
    public Result insert(@RequestBody SysFileInsertVo sysFileInsertVo) {
        Result result = ResultTool.success();
        Transaction trans = null;
        try {
            SysFile sysFile = new SysFile();
            BeanUtils.copyProperties(sysFileInsertVo, sysFile);
            sysFile.setId(UUIDUtils.simpleUuid());
            sysFile.setCreateUser(CurrentUser.getUser().getUserId());
            sysFile.setCreateTime(new Date());
            sysFile.setIsDeleted(IsDelete.FALSE.getCode());
            trans= TransUtils.getTrans();
            trans.begin();
            sysFileService.insert(sysFile);
            trans.commit();
        } catch (Exception e) {
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    /**
     * 删除文件表
     * @param id id
     * @return 删除结果
     */
    @DeleteMapping("delete")
    @ApiAuth(value="sysFile.delete",description="删除文件表")
    public Result delete(@RequestParam("id") String id) {
        Result result = ResultTool.success();
        Transaction trans = null;
        if (id == null|| id.isEmpty()) {
            result = ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
            return result;
        }
        try {
            trans= TransUtils.getTrans();
            trans.begin();
            sysFileService.delete(id,false);
            trans.commit();
        } catch (Exception e) {
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    /**
     * 修改文件表
     * @param sysFileUpdateVo 修改参数
     * @return 修改结果
     */
    @PostMapping("update")
    @ApiAuth(value="sysFile.update",description="修改文件表")
    public Result update(@RequestBody SysFileUpdateVo sysFileUpdateVo) {
        Result result = ResultTool.success();
        Transaction trans = null;
        try {
            SysFile sysFile = new SysFile();
            BeanUtils.copyProperties(sysFileUpdateVo, sysFile);
            sysFile.setUpdateUser(CurrentUser.getUser().getUserId());
            sysFile.setUpdateTime(new Date());
            trans= TransUtils.getTrans();
            trans.begin();
            sysFileService.update(sysFile);
            trans.commit();
        } catch (Exception e) {
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    /**
    * 根据id查询文件表
    * @param id id
    * @return 文件表结果
    */
    @GetMapping("selectById")
    @ApiAuth(value="sysFile.selectById",description="根据id查询文件表")
    public Result selectById(String id) {
        Result result = ResultTool.success();
        if(StringUtils.isEmpty(id)){
            result = ResultTool.fail(ResultCode.PARAM_NOT_COMPLETE);
            result.setMsg("id不能为空");
        }
        SysFile sysFile = sysFileService.selectById(id);
        result.setData(sysFile);
        return result;
    }

    /**
     * 分页查询查询文件表
     * @param sysFileSearchVo 查询参数
     * @return 查询结果
     */
    @PostMapping("pageQuery")
    @ApiAuth(value="sysFile.pageQuery",description="分页查询文件表")
    public Result select(@RequestBody SysFileSearchVo sysFileSearchVo, HttpServletRequest request) {
        Result result = ResultTool.success();
        String contextPath = request.getContextPath();
        PageUtil.setPage(sysFileSearchVo.getCurrent(),sysFileSearchVo.getSize());
        boolean isDeleted = false;
        if(null!=sysFileSearchVo.getDeleted()){
            isDeleted = sysFileSearchVo.getDeleted();
        }
        List<SysFile> select = sysFileService.select(sysFileSearchVo,isDeleted);
        return getResult(request, result, contextPath, select);
    }

    private Result getResult(HttpServletRequest request, Result result, String contextPath, List<SysFile> select) {
        List<SysFileOut> selectOut = new ArrayList<>();
        select.forEach(sysFile -> {
            SysFileOut sysFileOut = new SysFileOut();
            BeanUtils.copyProperties(sysFile, sysFileOut);
            sysFileOut.setFileTypeMean(FileType.getCodeMean(sysFile.getFileType()));
            selectOut.add(sysFileOut);
            String filePath = sysFile.getFilePath();
            filePath = filePath.replace("\\", "/");
            sysFileOut.setDownloadUrl(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                    + contextPath+"/"+"file/download/"+filePath);
            sysFileOut.setPreviewUrl(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
                    + contextPath+"/"+"file/preview/"+filePath);
        });
        result.setPageData(selectOut);
        return result;
    }


    /**
     * 恢复文件表
     * @param id id
     * @return 恢复结果
     */
    @PutMapping("recover")
    @ApiAuth(value="sysFile.recover",description="恢复文件表")
    private Result Recover(String id){
        Result result = ResultTool.success();
        SysFile sysFile = sysFileService.selectById(id);
        if(sysFile==null){
            result = ResultTool.fail(ResultCode.DATA_NULL);
            result.setMsg("文件不存在");
            return result;
        }
        Transaction trans = null;
        try {
            sysFile.setIsDeleted(false);
            sysFile.setUpdateTime(new Date());
            sysFile.setUpdateUser(CurrentUser.getUser().getUserId());
            trans = TransUtils.getTrans();
            trans.begin();
            sysFileService.update(sysFile);
            trans.commit();
        } catch (Exception e) {
            TransUtils.rollback(trans);
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    @DeleteMapping("deleteFile")
    @ApiAuth(value="sysFile.deleteFile",description="删除文件")
    private Result deleteFile(String id){
        Result result = ResultTool.success();
        SysFile sysFile = sysFileService.selectById(id);
        if(sysFile==null){
            result = ResultTool.fail(ResultCode.DATA_NULL);
            logger.error("文件不存在");
            return result;
        }
        try {
            sysFileService.delete(id,true);
            String filePath = fileSavePath+sysFile.getFilePath();
            FileUtils.deleteFile(filePath);
        } catch (Exception e) {
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
            return result;
        }
        return result;
    }

    @DeleteMapping("deleteAllFile")
    @ApiAuth(value="sysFile.deleteAllFile",description="删除所有文件")
    private Result deleteAllFile(){
        Result result = ResultTool.success();
        try {
            List<SysFile> sysFiles = sysFileService.select(new SysFileSearchVo(),true);
            sysFiles.forEach(sysFile -> {
                String filePath = fileSavePath+sysFile.getFilePath();
                FileUtils.deleteFile(filePath);
            });
            sysFileService.deleteAll();
        } catch (Exception e) {
            result = ResultTool.fail();
            logger.error(e.getMessage(), ExceptionUtils.getFullStackTrace(e));
        }
        return result;
    }
}
